﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Vibz.Common.Channel;
using System.Threading;
using Vibz.Server.Controller.UI;
using Vibz.Common;
using System.Reflection;
using Vibz.Common.Model;

namespace Vibz.Terminal
{
    public enum FormType { Home, ServerControl, ClientTerminal }
    public partial class FormContainer : Form
    {
        Form activeForm;
        Dictionary<FormType, Form> openForms;
        Logs _log;
        public FormContainer(Logs log)
        {
            InitializeComponent();
            _log = log;
            openForms = new Dictionary<FormType, Form>();
            OpenForm(FormType.Home, null);
        }
        public void OpenForm(FormType type, object args)
        {
            if (openForms.ContainsKey(type))
            {
                openForms[type].Focus();
                return;
            }
            switch (type)
            { 
                case FormType.Home:
                    activeForm = new FormHome(_log);
                    break;
                case FormType.ClientTerminal:
                    if(((object[])args).Length != 2)
                        throw new Exception("Invalid arguments.");
                    ModelInformation mInfo = (ModelInformation)((object[])args)[0];
                    SocketClient sClient = (SocketClient)((object[])args)[1];
                    activeForm = LoadTerminal(mInfo);
                    ((ClientTerminal)activeForm).InvokeStart(sClient, _log);
                    break;
                case FormType.ServerControl:
                    activeForm = new FormServer();
                    break;
            }
            activeForm.MdiParent = this;
            this.Text = activeForm.Text + " - Vibz Client";
            activeForm.FormBorderStyle = FormBorderStyle.None;
            activeForm.Dock = DockStyle.Fill;
            activeForm.Show();
            openForms.Add(type, activeForm);
        }

        ClientTerminal LoadTerminal(ModelInformation mInfo)
        {
            try
            {
                Assembly asm = Assembly.LoadFrom(mInfo.Client.Path);
                if (asm == null)
                    throw new Exception("The client does not exists.");

                Type t = asm.GetType(mInfo.Client.Type);
                if (t == null || !typeof(ClientTerminal).IsAssignableFrom(t))
                    throw new Exception("The type specified is not a valid client type. A client type should inherit ClientTerminal.");

                object[] args = mInfo.Client.Parameters.ToArray<object>();
                return (ClientTerminal)Activator.CreateInstance(t, args);
            }
            catch (TargetException tExc)
            {
                throw new Exception("Error occured while loading model manager. ", tExc);            
            }
            catch (Exception exc)
            {
                throw new Exception("Error occured while loading model manager. ", exc);
            }
        }
        private void toolConnect_Click(object sender, EventArgs e)
        {
            OpenForm(FormType.ServerControl, null);
        }

        private void toolHome_Click(object sender, EventArgs e)
        {
            OpenForm(FormType.Home, null);
        }
    }
}
